package com.example.mattrigle;

import java.util.ArrayList;
import java.util.List;

import com.example.mattrigle.CustomAnimation.TimerListener;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class SeekBar {

	// ==========================================================
	// Delegate & Callback
	// ==========================================================
	public abstract interface SeekBarListener {
		public void onSeekBarDragged(SeekBar obj, float progress);

		public void onSeekBarBeginDrag(SeekBar obj, float progress);

		public void onSeekBarDragging(SeekBar obj, float progress);
	}

	// ==========================================================
	// constant
	// ==========================================================
	private final int unit_point = 11;
	private final int unitOfFloat = 1;
	private final int labelOfFloat = 3;

	// ==========================================================
	// Field
	// ==========================================================
	private Drawable thumbDrawable = null;
	private Drawable thumbDrawablePressed = null;
	private Drawable thumb = null;
	private static Drawable labelDrawable = null;
	private static Drawable handDrawable = null;
	private Point cursorPoint = new Point(0, 0);
	private Paint inner = new Paint();
	private Paint outer = new Paint();
	private Paint unusedPaint = new Paint();
	private Paint labelPaint = new Paint();
	private Paint unitPaint = new Paint();
	private Paint barPaint = new Paint();
	private Paint sub_barPaint = new Paint();
	private View parent;
	private Context _context;

	private boolean isAppendCursorBG = false;
	private float unit_scale = 1f / (unit_point - 1);
	private float text_half_width = 0f;
	private float bar_half_width = 0f;
	private float sub_bar_half_width = 0f;
	private float thumbX, thumbDX;
	private float thumbY, thumbDY;
	private float maxThumbX = 1;
	private float maxThumbY = 1;
	private float minThumbX = 0;
	private float minThumbY = 0;
	private static int labelWidth;
	private static int labelHeight;
	private static int handWidth;
	private static int handHeight;

	// ==========================================================
	// Properties
	// ==========================================================
	public static final int HORIZONTAL = 2;
	public static final int VERTICAL = 1;
	private int direction = HORIZONTAL;

	public int getDirection() {
		return direction;
	}

	public int getLabelWidth() {
		return labelDrawable.getBounds().width();
	}

	private static int thumbWidth;

	public int getThumbWidth() {
		return thumbWidth;
	}

	private static int thumbHeight;

	public int getThumbHeight() {
		return thumbHeight;
	}

	private boolean hideCursor = false;

	public boolean isHideCursor() {
		return hideCursor;
	}

	public void setHideCursor(boolean hideCursor) {
		this.hideCursor = hideCursor;
	}

	private int width;

	public int getWidth() {
		return width - ((direction == HORIZONTAL) ? thumbWidth : 0);
	}

	public void setWidth(int width) {
		width = (width < 0) ? 0 : width;
		this.width = width + ((direction == HORIZONTAL) ? thumbWidth : 0);
		calView();
	}

	private float half_line_width = 1f;

	public float getLineWidth() {
		return half_line_width * 2;
	}

	public void setLineWidth(int line_width) {
		line_width = line_width < 1 ? 1 : line_width;

		this.half_line_width = line_width / 2f;
	}

	private int height;

	public int getHeight() {
		return height - ((direction == VERTICAL) ? thumbHeight : 0);
	}

	public void setHeight(int height) {
		if (height < 0)
			height = 0;
		this.height = height + ((direction == VERTICAL) ? thumbHeight : 0);
		calView();
	}

	private List<SeekBarListener> listerners = new ArrayList<SeekBarListener>();

	public void addListener(SeekBarListener listener) {
		listerners.add(listener);
	}

	public void removeListener(SeekBarListener listener) {
		listerners.remove(listener);
	}

	private SeekBarListener listener;

	public void setOnValueChanged(SeekBarListener listener) {
		this.listener = listener;
	}

	public static final int CURSOR_DIRECTION_L2R = 1;
	public static final int CURSOR_DIRECTION_R2L = 0;
	private int cursor_direction;

	public int getCursorDirection() {
		return cursor_direction;
	}

	public void setCursorDirection(int cursor_direction) {
		this.cursor_direction = (cursor_direction == CURSOR_DIRECTION_L2R || cursor_direction == CURSOR_DIRECTION_R2L) ? cursor_direction
				: CURSOR_DIRECTION_L2R;
	}

	private float scale = 0.5f;

	public float getScale() {
		return scale;
	}

	public void setScale(float scale) {
		this.scale = scale < 0.1f ? 0.1f : scale > 0.6f ? 0.6f : scale;
	}

	public static final int THEME_YELLOW = 3;
	public static final int THEME_RED = 2;
	public static final int THEME_BLUE = 1;
	public static final int THEME_GREEN = 0;
	public static final int THEME_RED_INVERT = 6;
	public static final int THEME_GREEN_INVERT = 7;
	public static final int THEME_YELLOW_INVERT = 8;
	private int theme;

	public int Theme() {
		return theme;
	}

	public void setTheme(int theme) {
		this.theme = (theme == THEME_RED || theme == THEME_BLUE
				|| theme == THEME_GREEN || theme == THEME_YELLOW
				|| theme == THEME_RED_INVERT || theme == THEME_GREEN_INVERT || theme == THEME_YELLOW_INVERT) ? theme
				: THEME_BLUE;

		switch (this.theme) {
		case THEME_RED:
			inner.setColor(0xffebd9e2);
			outer.setColor(0xfff886c5);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player3);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player3_pressed);
			break;
		case THEME_BLUE:
			inner.setColor(0xffd9e2eb);
			outer.setColor(0xff86c5f8);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player2);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player2_pressed);
			break;
		case THEME_GREEN:
			inner.setColor(0xffb4e396);
			outer.setColor(0xff6ac453);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player1);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player1_pressed);
			break;
		case THEME_YELLOW:
			inner.setColor(0xfffffca8);
			outer.setColor(0xfffff700);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player4);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player4_pressed);
			break;
		case THEME_RED_INVERT:
			inner.setColor(0xff86c5f8);
			outer.setColor(0xfff886c5);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player3);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player3_pressed);
			break;
		case THEME_GREEN_INVERT:
			inner.setColor(0xff86c5f8);
			outer.setColor(0xff6ac453);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player1);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player1_pressed);
			break;
		case THEME_YELLOW_INVERT:
			inner.setColor(0xff86c5f8);
			outer.setColor(0xfffff700);
			thumbDrawable = _context.getResources().getDrawable(
					R.drawable.player4);
			thumbDrawablePressed = _context.getResources().getDrawable(
					R.drawable.player4_pressed);
			break;
		}
		unusedPaint.setColor(0xffbfbfbf);
		if (labelDrawable == null)
			labelDrawable = _context.getResources().getDrawable(R.raw.ballon);
		labelWidth = (int) (labelDrawable.getIntrinsicWidth() * (scale + 0.2f) / 2);
		labelHeight = (int) (labelDrawable.getIntrinsicHeight()
				* (scale + 0.2f) / 2);
		thumbWidth = thumbDrawable.getIntrinsicWidth();
		thumbHeight = thumbDrawable.getIntrinsicHeight();
	}

	private Point offset = new Point(0, 0);

	public void setPosition(int x, int y) {
		offset.x = x - ((direction == HORIZONTAL) ? thumbWidth / 2 : width / 2);
		offset.y = y - ((direction == VERTICAL) ? thumbHeight / 2 : 0);
		calView();
	}

	public Point getPosition() {
		return new Point(offset.x
				+ ((direction == HORIZONTAL) ? thumbWidth / 2 : 0), offset.y
				+ ((direction == VERTICAL) ? thumbHeight / 2 : 0));
	}

	private boolean isShowUnit = true;

	public boolean IsShowUnit() {
		return isShowUnit;
	}

	public void setShowUnit(boolean isShowUnit) {
		this.isShowUnit = isShowUnit;
	}

	private boolean pressed = false;

	public boolean isDragging() {
		return pressed;
	}

	private float progress = 0.000f;

	public float getProgress(boolean isToggle) {
		return (isToggle) ? progress : Math.abs(1f - progress);
	}

	public float getProgress() {
		return (cursor_direction == CURSOR_DIRECTION_L2R) ? progress : Math
				.abs(1f - progress);
	}

	public void setProgress(float progress) {
		this.progress = progress < 0f ? 0f : progress > 1f ? 1f : progress;
		this.progress = ((cursor_direction == CURSOR_DIRECTION_L2R) ? progress
				: Math.abs(1f - progress));

		calView();
	}

	private boolean enable = true;

	public boolean getEnable() {
		return enable;
	}

	public void setEnable(boolean enable) {
		this.enable = enable;
	}

	private boolean hideLabel = true;

	public boolean isHideLabel() {
		return hideLabel;
	}

	public void setHideLabel(boolean hideLabel) {
		this.hideLabel = hideLabel;
	}

	private boolean hideHand = true;

	public boolean isHideHand() {
		return hideHand;
	}

	public void setHideHand(boolean hideHand) {
		this.hideHand = hideHand;
		if (!hideHand) {
			if (handDrawable == null) {
				handDrawable = _context.getResources().getDrawable(R.raw.hand);
				handWidth = (int) (handDrawable.getIntrinsicWidth()
						* (scale + 0.2f) / 2);
				handHeight = (int) (handDrawable.getIntrinsicHeight()
						* (scale + 0.2f) / 2);
			}
		}
	}

	private float max_length = 1f;

	public float getMaximumLength() {
		return max_length;
	}

	public void setMaximumLength(float length) {
		this.max_length = length;
		calView();
	}

	// ==========================================================
	// Process & Operand Method
	// ==========================================================
	private void calView() {
		thumbX = (progress * (width - thumbWidth));
		maxThumbX = (cursor_direction == CURSOR_DIRECTION_L2R ? (max_length * (width - thumbWidth))
				: width - thumbWidth);
		minThumbX = (cursor_direction == CURSOR_DIRECTION_R2L ? ((1f - max_length) * (width - thumbWidth))
				: 0);
		thumbX = thumbX > maxThumbX ? maxThumbX
				: thumbX < minThumbX ? minThumbX : thumbX;

		thumbY = (progress * (height - thumbHeight));
		maxThumbY = (cursor_direction == CURSOR_DIRECTION_L2R ? (max_length * (height - thumbHeight))
				: height - thumbHeight);
		minThumbY = (cursor_direction == CURSOR_DIRECTION_R2L ? ((1f - max_length) * (height - thumbHeight))
				: 0);
		thumbY = thumbY > maxThumbY ? maxThumbY
				: thumbY < minThumbY ? minThumbY : thumbY;

		switch (direction) {
		case HORIZONTAL:
			cursorPoint.x = (int) thumbX + offset.x + thumbWidth / 2;
			cursorPoint.y = (height - thumbHeight) / 2 + offset.y + thumbHeight
					/ 2;
			break;
		case VERTICAL:
			cursorPoint.x = (width - thumbWidth) / 2 + offset.x + thumbWidth
					/ 2;
			cursorPoint.y = (int) thumbY + offset.y + thumbHeight / 2;
			break;
		}

		parent.invalidate();
	}

	// ==========================================================
	// Constructor
	// ==========================================================
	public SeekBar(Context context, View parent, int direction,
			boolean isAppendCursorBG) {
		this._context = context;
		this.parent = parent;
		this.isAppendCursorBG = isAppendCursorBG;

		this.setTheme(THEME_BLUE);
		this.direction = (direction == VERTICAL || direction == HORIZONTAL) ? direction
				: HORIZONTAL;
		this.setPosition(0, 0);
		this.setCursorDirection(CURSOR_DIRECTION_L2R);
		this.setTextSize(30);
		this.setBarSize(11);
		this.setProgressTextColor(0xff383838);
		this.setBarColor(0xff383838);
		Typeface face = Typeface.createFromAsset(context.getAssets(),
				"fonts/THA0085.ttf");
		unitPaint.setTypeface(face);
		labelPaint.setTypeface(face);
		labelPaint.setTextSize(40);
		labelPaint.setColor(0xff383838);
		isRecycle = false;
	}

	// ==========================================================
	// Public Method
	// ==========================================================
	public int getCursorX() {
		return cursorPoint.x;
	}

	public int getCursorY() {
		return cursorPoint.y;
	}

	public Point getCursorPoint() {
		return cursorPoint;
	}

	public void setTextSize(int size) {
		unitPaint.setTextSize(size < 11 ? 11 : size);
		text_half_width = unitPaint.measureText("0.0") / 2f;
	}

	public void setBarSize(int size) {
		barPaint.setTextSize(size < 11 ? 11 : size);
		// text_half_width =
		// (this.direction==HORIZONTAL)?barPaint.measureText("|")/2f:barPaint.measureText("_")/2f;
		sub_barPaint.setTextSize(size / 2 < 6 ? 6 : size / 2);
	}

	public void setProgressTextColor(int color) {
		unitPaint.setColor(color);
	}

	public void setBarColor(int color) {
		barPaint.setColor(color);
	}

	private boolean iscoverLabel = false;

	public void setCoverLabel(boolean iscoverLabel) {
		this.iscoverLabel = iscoverLabel;
	}

	float aw = 1f;

	public void setSmoothScale(float aw) {
		this.aw = aw < 1f ? 1f : aw;
		this.setTextSize(((int) (40f * aw * 1.1)));
		this.setBarSize(((int) (11f * aw * 1.1)));
		labelPaint.setTextSize(((int) (40f * aw * 1.1)));
		labelWidth = (int) (aw * labelDrawable.getIntrinsicWidth()
				* (scale + 0.2f) / 2);
		labelHeight = (int) (aw * labelDrawable.getIntrinsicHeight()
				* (scale + 0.2f) / 2);
	}

	// ==========================================================
	// Animation Field
	// ==========================================================
	private CustomAnimation anim = new CustomAnimation();
	private RectF innerRect = null;
	private RectF outerRect = null;
	private RectF unusedRect = null;
	private float zoom_in_anim = 1.6f;
	private float zoom_anim = 0f;
	private boolean playing = false;
	private int alpha = 255;
	private int delay = 100;

	// ==========================================================
	// Animation Public Method
	// ==========================================================
	public boolean isPlaying() {
		return playing;
	}

	public int getAlpha() {
		return alpha;
	}

	public void fadeActiveAnimation() {
		zoom_anim = zoom_in_anim;
		playing = true;
		anim.setInterval(delay);
		alpha = 0;
		anim.setListener(new TimerListener() {

			@Override
			public void onTimeUpdate(CustomAnimation obj, long totalTime,
					long deltaTime) {
				zoom_anim -= (float) Math.abs(Math.sin(zoom_anim)) * 0.42;
				alpha = (int) (Math.sin(zoom_in_anim - zoom_anim) * 255);
				if (zoom_anim <= 0.15f) {
					anim.EndAnimation();
					zoom_anim = 0f;
					alpha = 255;
					if (parent != null)
						parent.postInvalidate();
					playing = false;
				} else if (parent != null)
					parent.postInvalidate();
			}
		});
		anim.StartAnimation();
		if (parent != null)
			parent.postInvalidate();
	}

	private Boolean isRecycle = false;

	public void finish() {
		/*try{
		isRecycle = true;
		if (thumb != null)
			((BitmapDrawable) this.thumb).getBitmap().recycle();
		if (thumbDrawable != null)
			((BitmapDrawable) this.thumbDrawable).getBitmap().recycle();
		if (thumbDrawablePressed != null)
			((BitmapDrawable) this.thumbDrawablePressed).getBitmap().recycle();
		}catch(Exception e){}*/
	}

	// ==========================================================
	// Event Method
	// ==========================================================
	public boolean onTouch(int action, float x, float y) {
		try{
		if (enable) {
			switch (direction) {
			case HORIZONTAL:
				if (action == MotionEvent.ACTION_DOWN) {
					int additionWidth = (height - thumbWidth) / 2;
					if (thumbX - additionWidth + offset.x <= x
							&& x <= thumbX + offset.x + thumbWidth
									+ additionWidth && y >= offset.y
							&& y <= height + offset.y) {
						pressed = true;
						thumbDX = (int) (x - thumbX);
						cursorPoint.x = (int) thumbX + offset.x + thumbWidth
								/ 2;
						cursorPoint.y = (height - thumbHeight) / 2 + offset.y
								+ thumbHeight / 2;

						float value = (float) thumbX
								/ (float) (width - thumbWidth);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (this.listener != null)
							this.listener.onSeekBarBeginDrag(this, progress);
						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners.get(i).onSeekBarBeginDrag(this,
									progress);

						parent.invalidate();
						return true;
					}
				} else if (action == MotionEvent.ACTION_UP
						|| action == MotionEvent.ACTION_CANCEL) {
					if (pressed) {
						pressed = false;
						float value = (float) thumbX
								/ (float) (width - thumbWidth);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (this.listener != null)
							this.listener.onSeekBarDragged(this, progress);
						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners.get(i).onSeekBarDragged(this,
									progress);
						parent.invalidate();
						return true;
					}
				} else if (action == MotionEvent.ACTION_MOVE) {
					if (pressed) {
						thumbX = (int) (x - thumbDX);
						thumbX = (thumbX < minThumbY) ? minThumbY
								: thumbX > maxThumbX ? maxThumbX : thumbX;
						cursorPoint.x = (int) thumbX + offset.x + thumbWidth
								/ 2;
						cursorPoint.y = (height - thumbHeight) / 2 + offset.y
								+ thumbHeight / 2;

						float value = (float) thumbX
								/ (float) (width - thumbWidth);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (listener != null)
							listener.onSeekBarDragging(this, progress);
						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners.get(i).onSeekBarDragging(this,
									progress);

						parent.invalidate();
						return true;
					}
				}
				break;
			case VERTICAL:
				if (action == MotionEvent.ACTION_DOWN) {
					int additionHeight = (width - thumbHeight) / 2;
					if (thumbY - additionHeight + offset.y <= y
							&& y <= thumbY + offset.y + thumbHeight
									+ additionHeight && x >= offset.x
							&& x <= width + offset.x) {
						pressed = true;
						thumbDY = (int) (y - thumbY);
						cursorPoint.x = (width - thumbWidth) / 2 + offset.x
								+ thumbWidth / 2;
						cursorPoint.y = (int) thumbY + offset.y + thumbHeight
								/ 2;

						float value = (float) thumbY
								/ (float) (height - thumbHeight);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (this.listener != null)
							this.listener.onSeekBarBeginDrag(this, progress);
						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners.get(i).onSeekBarBeginDrag(this,
									progress);

						parent.invalidate();
						return true;
					}
				} else if (action == MotionEvent.ACTION_UP
						|| action == MotionEvent.ACTION_CANCEL) {
					if (pressed) {

						pressed = false;
						if (action == MotionEvent.ACTION_UP) {

							float value = (float) thumbY
									/ (float) (height - thumbHeight);
							this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
									: Math.abs(1f - value);

							if (this.listener != null)
								this.listener.onSeekBarDragged(this, progress);
							for (int i = 0; i < this.listerners.size(); i++)
								this.listerners.get(i).onSeekBarDragged(this,
										progress);
						}

						parent.invalidate();
						return true;
					}
				} else if (action == MotionEvent.ACTION_MOVE) {
					if (pressed) {
						thumbY = (int) (y - thumbDY);
						thumbY = (thumbY < minThumbY) ? minThumbY
								: thumbY > maxThumbY ? maxThumbY : thumbY;

						cursorPoint.x = (width - thumbWidth) / 2 + offset.x
								+ thumbWidth / 2;
						cursorPoint.y = (int) thumbY + offset.y + thumbHeight
								/ 2;

						float value = (float) thumbY
								/ (float) (height - thumbHeight);
						this.progress = (cursor_direction == CURSOR_DIRECTION_L2R) ? value
								: Math.abs(1f - value);

						if (listener != null)
							listener.onSeekBarDragging(this, progress);

						for (int i = 0; i < this.listerners.size(); i++)
							this.listerners.get(i).onSeekBarDragging(this,
									progress);

						parent.invalidate();
						return true;
					}
				}

				break;
			}
		}}
		catch(Exception e){}
		return false;
	}

	public void drawLine(Canvas canvas) {
		if (isRecycle)
			return;
		try {
			switch (this.direction) {
			case HORIZONTAL:

				if (this.cursor_direction == CURSOR_DIRECTION_L2R) {
					innerRect = new RectF(offset.x
							- (isAppendCursorBG ? half_line_width : 0)
							+ thumbWidth / 2, (height / 2) + offset.y
							- half_line_width, (width - thumbWidth / 2)
							+ offset.x, (height / 2) + half_line_width
							+ offset.y);

					outerRect = new RectF(offset.x
							- (isAppendCursorBG ? half_line_width : 0)
							+ thumbWidth / 2, (height / 2) + offset.y
							- half_line_width, (thumbWidth / 2 + thumbX)
							+ offset.x, (height / 2) + half_line_width
							+ offset.y);

					unusedRect = new RectF((thumbWidth / 2 + maxThumbX)
							+ offset.x, (height / 2) + offset.y
							- half_line_width, (width - thumbWidth / 2)
							+ offset.x, (height / 2) + half_line_width
							+ offset.y);

				} else {
					innerRect = new RectF(offset.x
							- (isAppendCursorBG ? half_line_width : 0)
							+ thumbWidth / 2, (height / 2) + offset.y
							- half_line_width, (thumbWidth / 2 + thumbX)
							+ offset.x, (height / 2) + half_line_width
							+ offset.y);

					outerRect = new RectF(offset.x
							- (isAppendCursorBG ? half_line_width : 0)
							+ thumbWidth / 2, (height / 2) + offset.y
							- half_line_width, (width - thumbWidth / 2)
							+ offset.x, (height / 2) + half_line_width
							+ offset.y);

					unusedRect = new RectF(offset.x
							- (isAppendCursorBG ? half_line_width : 0)
							+ thumbWidth / 2, (height / 2) + offset.y
							- half_line_width, (width - thumbWidth / 2)
							+ offset.x, (height / 2) + half_line_width
							+ offset.y);

				}
				if (playing) {
					innerRect.top -= (zoom_anim * innerRect.height() / 2);
					innerRect.bottom += (zoom_anim * innerRect.height() / 2);
					// innerRect.left -= (zoom_anim * innerRect.width()/2);
					// innerRect.right += (zoom_anim * innerRect.width()/2);

					outerRect.top -= (zoom_anim * outerRect.height() / 2);
					outerRect.bottom += (zoom_anim * outerRect.height() / 2);
					// outerRect.left -= (zoom_anim * outerRect.width()/2);
					// outerRect.right += (zoom_anim * outerRect.width()/2);

					unusedRect.top -= (zoom_anim * unusedRect.height() / 2);
					unusedRect.bottom += (zoom_anim * unusedRect.height() / 2);
				}
				break;
			case VERTICAL:
				if (this.cursor_direction == CURSOR_DIRECTION_L2R) {
					innerRect = new RectF((width / 2) + offset.x
							- half_line_width, offset.y + thumbHeight / 2,
							(width / 2) + half_line_width + offset.x,
							(height - thumbHeight / 2) + offset.y
									+ (isAppendCursorBG ? half_line_width : 0));
					outerRect = new RectF((width / 2) + offset.x
							- half_line_width, offset.y + thumbHeight / 2,
							(width / 2) + half_line_width + offset.x,
							(thumbHeight / 2 + thumbY) + offset.y
									+ (isAppendCursorBG ? half_line_width : 0));
					unusedRect = new RectF((width / 2) + offset.x
							- half_line_width, 0, (width / 2) + half_line_width
							+ offset.x, (height - thumbHeight / 2) + offset.y
							+ (isAppendCursorBG ? half_line_width : 0));

				} else {
					innerRect = new RectF((width / 2) + offset.x
							- half_line_width, offset.y + thumbHeight / 2,
							(width / 2) + half_line_width + offset.x,
							(thumbHeight / 2) + thumbY + offset.y);
					outerRect = new RectF((width / 2) + offset.x
							- half_line_width, (thumbHeight / 2) + thumbY
							+ offset.y, (width / 2) + half_line_width
							+ offset.x, (height - thumbHeight / 2) + offset.y
							+ (isAppendCursorBG ? half_line_width : 0));
					unusedRect = new RectF((width / 2) + offset.x
							- half_line_width, offset.y + (thumbHeight / 2),
							(width / 2) + half_line_width + offset.x, offset.y
									+ minThumbY + (thumbHeight / 2));

				}
				if (playing) {
					// innerRect.top -= (zoom_anim * innerRect.height()/2);
					// innerRect.bottom += (zoom_anim * innerRect.height()/2);
					innerRect.left -= (zoom_anim * innerRect.width() / 2);
					innerRect.right += (zoom_anim * innerRect.width() / 2);

					// outerRect.top -= (zoom_anim * outerRect.height()/2);
					// outerRect.bottom += (zoom_anim * outerRect.height()/2);
					outerRect.left -= (zoom_anim * outerRect.width() / 2);
					outerRect.right += (zoom_anim * outerRect.width() / 2);

					unusedRect.left -= (zoom_anim * outerRect.width() / 2);
					unusedRect.right += (zoom_anim * outerRect.width() / 2);
				}
				break;
			}
			canvas.drawRect(innerRect, inner);
			canvas.drawRect(outerRect, outer);
			canvas.drawRect(unusedRect, unusedPaint);
		} catch (Exception e) {
		}
	}

	public void drawCursor(Canvas canvas) {

		if (this.hideCursor)
			return;

		thumb = (!pressed) ? thumbDrawable : thumbDrawablePressed;

		if (thumb == null || isRecycle)
			return;
		try {
			if (playing)
				thumb.setAlpha(alpha);

			switch (this.direction) {
			case HORIZONTAL: {
				int y = (height - thumbHeight) / 2;
				Rect tmp = new Rect((int) thumbX + offset.x, y + offset.y,
						(int) thumbX + thumbWidth + offset.x, y + thumbHeight
								+ offset.y);
				if (playing) {
					// innerRect.top -= (zoom_anim * innerRect.height()/2);
					// innerRect.bottom += (zoom_anim * innerRect.height()/2);
					tmp.top -= (zoom_anim * tmp.height() / 2);
					tmp.bottom += (zoom_anim * tmp.height() / 2);
				}
				thumb.setBounds(tmp);
				thumb.draw(canvas);
			}
				break;
			case VERTICAL: {
				int x = (width - thumbWidth) / 2;
				Rect tmp = new Rect(x + offset.x, (int) thumbY + offset.y, x
						+ thumbWidth + offset.x, (int) thumbY + thumbHeight
						+ offset.y);
				if (playing) {
					// innerRect.top -= (zoom_anim * innerRect.height()/2);
					// innerRect.bottom += (zoom_anim * innerRect.height()/2);
					tmp.left -= (zoom_anim * tmp.width() / 2);
					tmp.right += (zoom_anim * tmp.width() / 2);
				}
				thumb.setBounds(tmp);
				thumb.draw(canvas);
			}
				break;
			}
		} catch (Exception e) {
		}
	}

	public void drawUnit(Canvas canvas) {
		if (isRecycle)
			return;
		try{
		if (this.isShowUnit)
			switch (this.direction) {
			case HORIZONTAL:
				if (this.isPlaying()) {
					unitPaint.setAlpha((int) (0.5f * alpha));
					barPaint.setAlpha((int) (0.5f * alpha));
					sub_barPaint.setAlpha((int) (0.5f * alpha));
				} else {
					unitPaint.setAlpha(255);
					barPaint.setAlpha(255);
					sub_barPaint.setAlpha(255);
				}
				if (cursor_direction == CURSOR_DIRECTION_L2R)
					for (int i = 0; i < unit_point; i++) {
						float x = offset.x
								+ (float) ((unit_scale * i) * (width - thumbWidth))
								+ (thumbWidth / 2);
						canvas.drawText(
								(i == 0 || i == unit_point - 1) ? " " + i / 10
										: String.format("%." + unitOfFloat
												+ "f", i * unit_scale), x
										- text_half_width, ((float) height * 5)
										/ 6 + half_line_width + offset.y,
								unitPaint);
						canvas.drawText("|", x - bar_half_width,
								((float) height * 2) / 3 + half_line_width
										+ offset.y, barPaint);
						if (i < unit_point - 1) {
							x = offset.x
									+ (float) (((unit_scale * i) + 0.05f) * (width - thumbWidth))
									+ (thumbWidth / 2);
							canvas.drawText("|", x - sub_bar_half_width,
									((float) height * 3) / 5 + half_line_width
											+ offset.y, sub_barPaint);
						}
					}
				else
					for (int i = unit_point; i >= 0; i--) {
						float x = offset.x
								+ (float) ((i * unit_scale) * (width - thumbWidth))
								+ (thumbWidth / 2);
						canvas.drawText(
								(i == 0 || i == unit_point - 1) ? " " + i / 10
										: String.format("%." + unitOfFloat
												+ "f", i * unit_scale), x
										- text_half_width, offset.y, unitPaint);
						canvas.drawText("|", x - bar_half_width, (height / 2)
								+ half_line_width + offset.y, barPaint);
						if (i > 1) {
							x = offset.x
									+ (float) (((i * unit_scale) + 0.05f) * (width - thumbWidth))
									+ (thumbWidth / 2);
							canvas.drawText("|", x - sub_bar_half_width,
									(height / 2) + half_line_width + offset.y,
									sub_barPaint);
						}
					}
				break;
			case VERTICAL:
				/*
				 * if(cursor_direction==CURSOR_DIRECTION_L2R) for(int
				 * i=0;i<unit_point;i++) { float y =
				 * (float)((i*unit_scale)*(height-thumbHeight*2)) + offset.y +
				 * thumbHeight;
				 * canvas.drawText(""+dfm.format(i*unit_scale*weight), offset.x
				 * - bar_half_width - 5, y, unitPaint);
				 * canvas.drawText("_",offset.x - 5 , y, barPaint); } else
				 * for(int i=unit_point;i>0;i--) { float y =
				 * (float)((i*unit_scale)*(height-thumbHeight*2)) + offset.y +
				 * thumbHeight;
				 * canvas.drawText(""+dfm.format(i*unit_scale*weight), offset.x
				 * - bar_half_width - 5, y-3, unitPaint);
				 * canvas.drawText("_",offset.x - 5 , y-3, barPaint); }
				 */
				break;
			}}
		catch(Exception e){}
	}

	public void drawLabel(Canvas canvas) {
		if (isRecycle)
			return;
		try {
			if (!hideLabel && (pressed || iscoverLabel)) {
				if (playing)
					labelDrawable.setAlpha(alpha);
				switch (this.direction) {
				case HORIZONTAL:
					int y = -5 + (height - labelHeight) / 2;
					labelDrawable.setBounds((int) thumbX + offset.x - 5
							- (labelWidth - thumbWidth) / 2, y + offset.y
							- labelHeight / 2, (int) thumbX + 5
							+ (labelWidth + thumbWidth) / 2 + offset.x, y
							+ offset.y + labelHeight / 2);

					labelDrawable.draw(canvas);
					String label = String
							.format("%." + labelOfFloat + "f",
									(cursor_direction == CURSOR_DIRECTION_L2R) ? progress
											: Math.abs(1f - progress));
					canvas.drawText(
							label,
							thumbX
									+ offset.x
									- (-thumbWidth + labelPaint
											.measureText(label)) / 2, y
									+ offset.y, labelPaint);
					break;
				case VERTICAL:
					break;
				}
			}
		} catch (Exception e) {
		}
	}

	public void drawHand(Canvas canvas) {
		if (isRecycle)
			return;
		try {
			if (!hideHand) {
				if (playing)
					handDrawable.setAlpha(alpha);
				handDrawable.setBounds(getCursorX()
						- (int) ((handWidth * 0.55f) / 2), getCursorY(),
						getCursorX() + (int) ((handWidth * 1.45f) / 2),
						getCursorY() + handHeight);
				handDrawable.draw(canvas);
			}
		} catch (Exception e) {
		}
	}
}